package client;

import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Cylinder;
import com.jme3.scene.shape.Sphere;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class ObjectPlayer 
{
    BitmapFont guiFont;
    static Material matWire;
    private CharacterControl player;
    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(2f, 1.8f, 1);
    private Vector3f walkDirection = new Vector3f();
    private boolean left = false, right = false, up = false, down = false;
    boolean wireframe = false;
    Camera cam;
    PlayerCamera ccam;
    Spatial playerNode;
    static Geometry collisionMarker;
    long lastpressed;
    long nowpress;
    int choiceSize = 6;
    static Geometry tracker;
    boolean console;
    boolean isBuild = true;
    boolean canRotate;
    boolean clipping;
    Quaternion frame = new Quaternion();
    float angleLast;
    static LundWidget lund = new LundWidget();
    //TODO: fix camera rotation    
    public void initPlayer(SimpleApplication app)
    {
        matWire = new Material(Main.appref.getAssetManager(), 
                "Common/MatDefs/Misc/Unshaded.j3md");
        matWire.getAdditionalRenderState().setWireframe(true);
        matWire.setColor("Color", ColorRGBA.Green);
        console = false;
        guiFont = app.getAssetManager().loadFont("Interface/Fonts/Default.fnt");
        playerNode = Main.appref.getAssetManager().loadModel("Models/player.j3o");
        player = new CharacterControl(capsuleShape, 0.1f);
        player.setJumpSpeed(45);
        player.setFallSpeed(50);
        player.setGravity(150);
        player.setMaxSlope(30f);
        player.setPhysicsLocation(new Vector3f(0, 10, 0));
        player.setUseViewDirection(true);
        cam = Main.appref.getCamera();
        ccam = new PlayerCamera(cam, playerNode, Main.appref.getInputManager());
        ccam.setDragToRotate(false);
        ccam.setSmoothMotion(true);
        ccam.setUpVector(Main.appref.getCamera().getUp());
        ccam.setMaxDistance(45);
        ccam.setMinDistance(85);
        ccam.setTrailingEnabled(true);
        ccam.setTrailingSensitivity(1.25f);
        ccam.setLookAtOffset(new Vector3f(0,15,0));
        ccam.setDefaultVerticalRotation(0.15f);
        ccam.setDefaultHorizontalRotation(-1.5f);
        ccam.setInvertVerticalAxis(true);
        ccam.setMaxVerticalRotation(2);
        ccam.setMinVerticalRotation(-0.75f);
        playerNode.addControl(player);
        playerNode.addControl(ccam);
        PhysicsController.addChild(player);
        Main.appref.getRootNode().attachChild(playerNode);
        clipping = true;
        lastpressed = System.currentTimeMillis();
    }
    
    public Vector3f getLocation()
    {
        return player.getPhysicsLocation();
    }
    
    public void timeSync()
    {
        nowpress = System.currentTimeMillis();
    }
    
    public boolean setClip(boolean clip)
    {
        clipping = clip;
        return clip;
        //redundancies help java grow!
    }
    
    private void createCollisionMarker() 
    {
        Sphere s = new Sphere(6, 6, 1);
        collisionMarker = new Geometry("collisionMarker");
        collisionMarker.setMesh(s);
        Material mat = new Material(Main.appref.getAssetManager(),
                "Common/MatDefs/Light/Lighting.j3md");
        mat.setBoolean("m_UseMaterialColors", true);
        mat.setColor("m_Diffuse", ColorRGBA.Orange);
        mat.setColor("GlowColor", ColorRGBA.Orange);
        mat.setFloat("Shininess", 64f);
        collisionMarker.setMaterial(mat);
        Main.appref.getRootNode().attachChild(collisionMarker);
    }
    
    protected void initCrossHairs(SimpleApplication app) 
    {
        //guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
        BitmapText ch = new BitmapText(guiFont, false);
        ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
        ch.setText("+"); // crosshairs
        ch.setLocalTranslation( // center
                app.getGuiViewPort().getCamera().getWidth() / 2 -
                guiFont.getCharSet().getRenderedSize() / 3 * 2,
                app.getGuiViewPort().getCamera().getHeight() / 2 +
                ch.getLineHeight() / 2, 0);
        app.getGuiNode().attachChild(ch);
    }
    
    public void setupKeys(SimpleApplication app) 
    {
        //app.getInputManager().clearMappings();
        app.getInputManager().deleteMapping("SIMPLEAPP_Exit");
        if (isBuild) 
        {
            app.getInputManager().addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
            app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
            app.getInputManager().addMapping("place", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
            app.getInputManager().addMapping("delete", new MouseButtonTrigger(MouseInput.BUTTON_MIDDLE));
            app.getInputManager().addMapping("npc", new KeyTrigger(KeyInput.KEY_F));
            app.getInputManager().addMapping("scrollup", new KeyTrigger(KeyInput.KEY_E));
            app.getInputManager().addMapping("scrolldown", new KeyTrigger(KeyInput.KEY_Q));
            app.getInputManager().addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
            app.getInputManager().addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
            app.getInputManager().addMapping("Forwards", new KeyTrigger(KeyInput.KEY_W));
            app.getInputManager().addMapping("Backs", new KeyTrigger(KeyInput.KEY_S));
            app.getInputManager().addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
            app.getInputManager().addMapping("sizeup", new KeyTrigger(KeyInput.KEY_R));
            app.getInputManager().addMapping("sizedown", new KeyTrigger(KeyInput.KEY_V));
            app.getInputManager().addMapping("console", new KeyTrigger(KeyInput.KEY_GRAVE));
            app.getInputManager().addMapping("noclip", new KeyTrigger(KeyInput.KEY_N));
            app.getInputManager().addMapping("SIMPLEAPP_Exit", new KeyTrigger(KeyInput.KEY_ESCAPE));
            app.getInputManager().addListener(actionListener, "wireframe");
            app.getInputManager().addListener(actionListener, "Lefts");
            app.getInputManager().addListener(actionListener, "Rights");
            app.getInputManager().addListener(actionListener, "Ups");
            app.getInputManager().addListener(actionListener, "Downs");
            app.getInputManager().addListener(actionListener, "Forwards");
            app.getInputManager().addListener(actionListener, "scrollup");
            app.getInputManager().addListener(actionListener, "scrolldown");
            app.getInputManager().addListener(actionListener, "Backs");
            app.getInputManager().addListener(actionListener, "shoot");
            app.getInputManager().addListener(actionListener, "place");
            app.getInputManager().addListener(actionListener, "Jump");
            app.getInputManager().addListener(actionListener, "npc");
            app.getInputManager().addListener(actionListener, "delete");
            app.getInputManager().addListener(actionListener, "sizeup");
            app.getInputManager().addListener(actionListener, "sizedown");
            app.getInputManager().addListener(actionListener, "console");
            app.getInputManager().addListener(actionListener, "noclip");
            app.getInputManager().addListener(actionListener, "SIMPLEAPP_Exit");
        }
        else if(!isBuild)
        {
            app.getInputManager().addMapping("scrollup", new KeyTrigger(KeyInput.KEY_E));
            app.getInputManager().addMapping("scrolldown", new KeyTrigger(KeyInput.KEY_Q));
            app.getInputManager().addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
            app.getInputManager().addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
            app.getInputManager().addMapping("Forwards", new KeyTrigger(KeyInput.KEY_W));
            app.getInputManager().addMapping("Backs", new KeyTrigger(KeyInput.KEY_S));
            app.getInputManager().addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
            app.getInputManager().addMapping("console", new KeyTrigger(KeyInput.KEY_GRAVE));
            app.getInputManager().addMapping("SIMPLEAPP_Exit", new KeyTrigger(KeyInput.KEY_ESCAPE));
            app.getInputManager().addListener(actionListener, "Lefts");
            app.getInputManager().addListener(actionListener, "Rights");
            app.getInputManager().addListener(actionListener, "Ups");
            app.getInputManager().addListener(actionListener, "Downs");
            app.getInputManager().addListener(actionListener, "Forwards");
            app.getInputManager().addListener(actionListener, "scrollup");
            app.getInputManager().addListener(actionListener, "scrolldown");
            app.getInputManager().addListener(actionListener, "Backs");
            app.getInputManager().addListener(actionListener, "Jump");
            app.getInputManager().addListener(actionListener, "console");
            app.getInputManager().addListener(actionListener, "SIMPLEAPP_Exit");
        }
    }
    
    public void unbindBuild(SimpleApplication app) 
    {
        app.getInputManager().deleteMapping("wireframe");
        app.getInputManager().deleteMapping("shoot");
        app.getInputManager().deleteMapping("place");
        app.getInputManager().deleteMapping("delete");
        app.getInputManager().deleteMapping("npc");
        app.getInputManager().deleteMapping("scrollup");
        app.getInputManager().deleteMapping("scrolldown");
        app.getInputManager().deleteMapping("Lefts");
        app.getInputManager().deleteMapping("Rights");
        app.getInputManager().deleteMapping("Forwards");
        app.getInputManager().deleteMapping("Backs");
        app.getInputManager().deleteMapping("Jump");
        app.getInputManager().deleteMapping("sizeup");
        app.getInputManager().deleteMapping("sizedown");
        app.getInputManager().deleteMapping("noclip");
    }
    
    public void unbindNorm(SimpleApplication app) 
    {
        app.getInputManager().deleteMapping("scrollup");
        app.getInputManager().deleteMapping("scrolldown");
        app.getInputManager().deleteMapping("Lefts");
        app.getInputManager().deleteMapping("Rights");
        app.getInputManager().deleteMapping("Forwards");
        app.getInputManager().deleteMapping("Backs");
        app.getInputManager().deleteMapping("Jump");
    }

    
    private ActionListener actionListener = new ActionListener() 
    {
        public void onAction(String binding, boolean keyPressed, float tpf) 
        {
            if (binding.equals("wireframe") && !keyPressed) 
            {
                wireframe = !wireframe;
                if (!wireframe) 
                {
                    TerrainControl.getTerrain().setMaterial(matWire);
                } 
                else 
                {
                    TerrainControl.getTerrain().setMaterial(TerrainControl.matRock);
                }
            } 
            else if (binding.equals("shoot") && !keyPressed) 
            {
                lastpressed = System.currentTimeMillis();
                /*if (nowpress > lastpressed + 10) 
                {
                    lastpressed = System.currentTimeMillis();
                    Vector3f origin = cam.getWorldCoordinates(new Vector2f(Main.api.getGuiViewPort().getCamera().getWidth() / 2, Main.api.getGuiViewPort().getCamera().getHeight() / 2), 0.0f);
                    Vector3f direction = cam.getWorldCoordinates(new Vector2f(Main.api.getGuiViewPort().getCamera().getWidth() / 2, Main.api.getGuiViewPort().getCamera().getHeight() / 2), 0.3f);
                    direction.subtractLocal(origin).normalizeLocal();
                    Ray ray = new Ray(origin, direction);
                    CollisionResults results = new CollisionResults();
                    int numCollisions = Main.rn.collideWith(ray, results);
                    if (numCollisions > 0) 
                    {
                        CollisionResult hit = results.getClosestCollision();
                        if (collisionMarker == null) 
                        {
                            createCollisionMarker();
                        }
                        Vector2f loc = new Vector2f(hit.getContactPoint().x, hit.getContactPoint().z);
                        float height = Main.ter.terrain.getHeight(loc);
                        System.out.println("collide " + hit.getContactPoint() + ", height: " + height + ", distance: " + hit.getDistance());
                        collisionMarker.setLocalTranslation(new Vector3f(hit.getContactPoint().x, height, hit.getContactPoint().z));
                        particle_fire_small bop = new particle_fire_small("Fire",new Vector3f(hit.getContactPoint().x, height, hit.getContactPoint().z),ColorRGBA.Orange);
                        bop.create();
                        bop.start();
                    }
                }*/
                Spatial spa = Main.appref.getAssetManager().loadModel("Models/arrow.j3o");
                Spatial sphg = Main.spawning.createModel(Main.appref, Vector3f.ZERO, spa, "01ddf");
                sphg.setLocalTranslation(Main.player.getLocation().add(Main.player.cam.getDirection().mult(5)));
                sphg.rotate(Main.player.cam.getRotation());
                Material mat = new Material(Main.appref.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
                mat.setBoolean("UseMaterialColors", true);
                mat.setColor("Diffuse", ColorRGBA.Orange);
                mat.setColor("Specular", ColorRGBA.White);
                mat.setFloat("Shininess", 12);
                mat.setBoolean("VertexLighting", false);
                mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Back);
                sphg.setMaterial(mat);
                RigidBodyControl sphc = new Projectile(new SphereCollisionShape(0.6f),150);
                sphc.setCcdMotionThreshold(0.1f);
                sphc.setLinearVelocity(Main.player.cam.getDirection().mult(450));
                sphg.addControl(sphc);
                Main.rendernode.attachChild(sphg);
                PhysicsController.addChild(sphc);
            }
            else if (binding.equals("delete") && !keyPressed) 
            {
                if (nowpress > lastpressed + 100) 
                {
                    lastpressed = System.currentTimeMillis();
                    Vector3f origin = cam.getWorldCoordinates(new Vector2f(Main.appref.getGuiViewPort().getCamera().getWidth() / 2, Main.appref.getGuiViewPort().getCamera().getHeight() / 2), 0.0f);
                    Vector3f direction = cam.getWorldCoordinates(new Vector2f(Main.appref.getGuiViewPort().getCamera().getWidth() / 2, Main.appref.getGuiViewPort().getCamera().getHeight() / 2), 0.3f);
                    direction.subtractLocal(origin).normalizeLocal();
                    Ray ray = new Ray(origin, direction);
                    CollisionResults results = new CollisionResults();
                    int numCollisions = Main.rendernode.collideWith(ray, results);
                    if (numCollisions > 0) 
                    {
                        CollisionResult hit = results.getClosestCollision();
                        RigidBodyControl rb = hit.getGeometry().getControl(RigidBodyControl.class);
                        Spatial node = hit.getGeometry();
                        if (!"terrain".equals(node.getParent().getName()) && !node.equals(Main.appref.getRootNode())
                                && !node.equals(Main.gameScene)) 
                        {
                            if (hit.getGeometry() == tracker) 
                            {
                                hit = results.getFarthestCollision();
                                if(hit.getGeometry() != null)
                                {
                                    Node die = new Node();
                                    die.attachChild(hit.getGeometry());
                                    die.addControl(rb);
                                    PhysicsController.killChild(die);
                                }
                            }
                            else 
                            {
                                Node die = new Node();
                                die.attachChild(hit.getGeometry());
                                die.addControl(rb);
                                PhysicsController.killChild(die);
                            }
                        }
                    }
                }
            }
            else if (binding.equals("Lefts")) 
            {
                if(keyPressed){left = true;} else {left = false;}
            } 
            else if (binding.equals("Rights")) 
            {
                if(keyPressed){right = true;} else {right = false;}
            } 
            else if (binding.equals("Forwards")) 
            {
                if(keyPressed){up = true;} else {up = false;}
            } 
            else if (binding.equals("Backs")) 
            {
                if(keyPressed){down = true;} else {down = false;}
            }
            else if (binding.equals("Jump")) 
            {
                player.jump();
            }
            else if (binding.equals("scrollup") && !keyPressed) 
            {
                Main.gameinterface.scrollUp();
            }
            else if (binding.equals("scrolldown") && !keyPressed) 
            {
                Main.gameinterface.scrollDown();
            }
            else if (binding.equals("sizeup") && !keyPressed) 
            {
                if (choiceSize < 15) 
                {
                    choiceSize++;
                }
                else
                {
                    choiceSize--;
                }
            }
            else if (binding.equals("sizedown") && !keyPressed) 
            {
                if (choiceSize > 1) 
                {
                    choiceSize--;
                }
                else
                {
                    choiceSize++;
                }
            }
            else if (binding.equals("console") && !keyPressed) 
            {
                if(console == false)
                {
                    if(!isBuild)
                    {
                        Main.player.unbindNorm(Main.appref);
                    }
                    else
                    {
                        Main.player.unbindBuild(Main.appref);
                    }
                    
                    Main.gameinterface.nifty.showPopup(Main.gameinterface.nifty.getCurrentScreen(), "console", Main.gameinterface.consolePop);
                    console = true;
                }
                else if(console == true)
                {
                    Main.player.setupKeys(Main.appref);
                    Main.gameinterface.nifty.closePopup("console");
                    console = false;
                }
            }
            else if (binding.equals("place") && !keyPressed) 
            {
                if (nowpress > lastpressed + 100) 
                {
                    Main.spawning.passSpawn(Main.appref);
                }
            }
            else if (binding.equals("npc") && !keyPressed) 
            {
                if (nowpress > lastpressed + 100) 
                {
                    lastpressed = System.currentTimeMillis();
                    Vector3f origin = cam.getWorldCoordinates(new Vector2f(Main.appref.getGuiViewPort().getCamera().getWidth() / 2, Main.appref.getGuiViewPort().getCamera().getHeight() / 2), 0.0f);
                    Vector3f direction = cam.getWorldCoordinates(new Vector2f(Main.appref.getGuiViewPort().getCamera().getWidth() / 2, Main.appref.getGuiViewPort().getCamera().getHeight() / 2), 0.3f);
                    direction.subtractLocal(origin).normalizeLocal();
                    Ray ray = new Ray(origin, direction);
                    CollisionResults results = new CollisionResults();
                    int numCollisions = Main.appref.getRootNode().collideWith(ray, results);
                    if (numCollisions > 0) 
                    {
                        CollisionResult hit = results.getClosestCollision();
                        Main.npchandle.spawnNPCNoder(Main.appref, new Vector3f(hit.getContactPoint().x, hit.getContactPoint().y + 2, hit.getContactPoint().z));
                    }
                }
            }
            else if (binding.equals("noclip") && !keyPressed)
            {
                if(clipping == true)
                {
                    clipping = false;
                    lund.printConsoleInfo("Noclip set to: " + clipping);
                    player.setPhysicsLocation(cam.getLocation());
                }
                else
                {
                    clipping = true;
                    lund.printConsoleInfo("Noclip set to: " + clipping);
                }
            }
            else if (binding.equals("SIMPLEAPP_Exit") && !keyPressed)
            {
                JFrame frame = new JFrame();
                int n = JOptionPane.showConfirmDialog(frame,
                        "Are you sure you want to exit the program?",
                        "Lund",
                        JOptionPane.YES_NO_OPTION);
                if(n == JOptionPane.YES_OPTION)
                {
                    Main.appref.stop();
                }
                else
                {
                    frame.dispose();
                }
            }
        }
    };
    
    public void createWire()
    {
        Box temp = new Box(Vector3f.ZERO,6f,6f,6f);
        tracker = new Geometry("Tracker",temp);
        tracker.setName("spawnTrack");
        tracker.setMaterial(matWire);
        tracker.setModelBound(new BoundingBox(new Vector3f(0,0,0),0,0,0));
        //tracker.setLocalTranslation(Main.play.getLocation());
        Main.rendernode.attachChild(tracker);
    }
    
    public void moveWire(Vector3f vec)
    {
        tracker.setLocalTranslation(vec);
    }
    
    public void resizeWire(int scale, int shape)
    {
        switch(shape)
        {
            case 1:
                tracker.removeFromParent();
                Box tempb = new Box(Vector3f.ZERO,scale,scale,scale);
                tracker = new Geometry("Box",tempb);
                tracker.setMaterial(matWire);
                Main.rendernode.attachChild(tracker);
                break;
            case 2:
                tracker.removeFromParent();
                Sphere temp = new Sphere(8,8,scale);
                tracker = new Geometry("Sphere",temp);
                tracker.setMaterial(matWire);
                Main.rendernode.attachChild(tracker);
                break;
            case 3:
                tracker.removeFromParent();
                Cylinder temp3 = new Cylinder(6, 18, scale, scale, true);
                tracker = new Geometry("Cylinder",temp3);
                tracker.setMaterial(matWire);
                Main.rendernode.attachChild(tracker);
                break;
            default:
                System.out.println("Incorrect reshape parameter specified!");
                break;
        }
    }
    
    public Vector3f getLook()
    {
        Vector3f origin = cam.getWorldCoordinates(new Vector2f(Main.appref.getGuiViewPort().getCamera().getWidth() / 2, Main.appref.getGuiViewPort().getCamera().getHeight() / 2), 0.0f);
        Vector3f direction = cam.getWorldCoordinates(new Vector2f(Main.appref.getGuiViewPort().getCamera().getWidth() / 2, Main.appref.getGuiViewPort().getCamera().getHeight() / 2), 0.3f);
        direction.subtractLocal(origin).normalizeLocal();
        Ray ray = new Ray(origin, direction);
        CollisionResults results = new CollisionResults();
        int numCollisions = Main.rendernode.collideWith(ray, results);
        if (numCollisions > 0) 
        {
            CollisionResult hit = results.getClosestCollision();
            if(hit.getGeometry() == tracker)
            {
                return results.getFarthestCollision().getContactPoint();
            }
            else
            {
                return hit.getContactPoint();
            }
        }
        else
        {
            return new Vector3f(0,0,0);
        }
    }
    
    public void reshapeWire(int shape)
    {
        if (isBuild) {
            switch (shape) {
                case 1:
                    tracker.removeFromParent();
                    Box tempb = new Box(Vector3f.ZERO, 6f, 6f, 6f);
                    tracker = new Geometry("Box", tempb);
                    tracker.setMaterial(matWire);
                    Main.rendernode.attachChild(tracker);
                    break;
                case 2:
                    tracker.removeFromParent();
                    Sphere temp = new Sphere(8, 8, 6);
                    tracker = new Geometry("Sphere", temp);
                    tracker.setMaterial(matWire);
                    Main.rendernode.attachChild(tracker);
                    break;
                case 3:
                    tracker.removeFromParent();
                    Cylinder temp3 = new Cylinder(6, 18, 5, 5, true);
                    tracker = new Geometry("Cylinder", temp3);
                    tracker.setMaterial(matWire);
                    Main.rendernode.attachChild(tracker);
                    break;
                default:
                    System.out.println("Incorrect reshape parameter specified!");
                    break;
            }
        }
    }
    
    public void playerTeleport(Vector3f vec)
    {
        player.setPhysicsLocation(vec);
    }
    
    public void handsUpdate(int handState)
    {
        switch(handState)
        {
            case 1:
            {
                if(Main.appref.getStateManager().getState(ViewPortState.class).getRoot().hasChild(Main.appref.getStateManager().getState(ViewPortState.class).handsnode))
                {
                    Main.appref.getStateManager().getState(ViewPortState.class).getRoot().detachChild(Main.appref.getStateManager().getState(ViewPortState.class).handsnode);
                }
                break;
            }
            case 2:
            {
                if(!Main.appref.getStateManager().getState(ViewPortState.class).getRoot().hasChild(Main.appref.getStateManager().getState(ViewPortState.class).handsnode))
                {
                    Main.appref.getStateManager().getState(ViewPortState.class).getRoot().attachChild(Main.appref.getStateManager().getState(ViewPortState.class).handsnode);
                }
                break;
            }
            default:
            {
                lund.printConsoleError("Incorrect handState specified!");
                break;
            }
        }
        
    }
            
    
    public void playerUpdate(float tpf, SimpleApplication app)
    {
        cam = app.getCamera();
        Vector3f camDir = cam.getDirection().clone().multLocal(0.7f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.7f);
        walkDirection.set(0, 0, 0);
        //player.setViewDirection(cam.getDirection());
        //System.out.println(ccam.getVerticalRotation() + " - " + ccam.getHorizontalRotation());
        if(isBuild)
        {
            handsUpdate(1);
        }
        else
        {
            handsUpdate(2);
        }
        if (left)
        {
            walkDirection.addLocal(camLeft);
        }
        if (right)
        {
            walkDirection.addLocal(camLeft.negate());
        }
        if (up)
        {
            walkDirection.addLocal(camDir);
        }
        if (down)
        {
            walkDirection.addLocal(camDir.negate());
        }
        Vector3f viewDir = new Vector3f(walkDirection.x,0,walkDirection.z);
        player.setViewDirection(viewDir);
        Vector3f dir = cam.getDirection();
        if(clipping == true)
        {
            player.setWalkDirection(walkDirection);
        }
        else
        {
            cam.setLocation(cam.getLocation().add(walkDirection));
        }
        float angleDir = dir.angleBetween(Vector3f.UNIT_Y);
        if(angleDir > 0.05f && angleDir < 3f)
        {
            canRotate = true;
        }
        else if(angleDir < 0.05f || angleDir > 3f)
        {
            canRotate = false;
        }
        if(canRotate == true)
        {
            frame.fromAxes(cam.getLeft(), cam.getUp(), dir);
            frame.normalizeLocal();
            cam.setAxes(frame);
        }
        Main.lights.updateViews(getLocation().distance(getLook()));
        /*handsnode.setLocalTranslation(cam.getLocation());
        handsnode.setLocalRotation(cam.getRotation());
        handsnode.setLocalRotation(new Quaternion(cam.getRotation().getW(),
                cam.getRotation().getX(),
                cam.getRotation().getY(),
                cam.getRotation().getZ()
                ));*/
    }
}
